"""
World
Tracks where everything is. Also, tests distance and collisions.
"""
import logging

#import boat, island, fish, pirates, triggers, port
from point import Point, AxisAlignedBoundingBox
from baseClasses import CoordPlane


class CollisionError(Exception):
    """ Represents an attempt to move one object into another. """
    def __init__(self, collider, colliderLoc, collidee, collideeLoc):
        Exception.__init__(self)
        self.collider = collider
        self.colliderLoc = colliderLoc
        self.collidee = collidee
        self.collideeLoc = collideeLoc


class World(CoordPlane):
    """ Maintains the locations of game objects, and the landscape. """
    # Location by object -> x,y are floats
    # items[<item>] => Point(x,y)
    items = {}
    # Object by location -> x,y are integers
    # locations[(x,y)] => item
    locations = {}
    tiles = {}
    game = None
    dirty = False

    logger = logging.getLogger("engine.world")

    def __init__(self, itemLocs={}, game=None):
        super(World, self).__init__(self, itemLocs, game)

    def __str__(self):
        return '<World(%i) at %s>' % (len(self.items), id(self))
    
    def __repr__(self):
        return 'World(%r)' % (self.items)
    
    # Game Objects
    # More efficient to just delete these, but "clearer" to leave them.
    def moveItem(self, item, vector):
        """ Move an object by a relative vector. """
        return super(World, self).moveItem(item, vector)
        
    def moveItemTo(self, item, point):
        """ Move an item to a specific location. """
        return super(World, self).moveItemTo(item, point)
        
    def append(self, item, point):
        """ Add a non-pre-extant item. """
        return super(World, self).append(item, point)

    def getCoord(self, item):
        """ Return the location of a specific object. """
        return super(World, self).getCoord(item)

    def getNearestItem(self, source, targetType):
        return super(World, self).getNearestItem(source, targetType)
    
    def getItems(self, x, y, w, h):
        return super(World, self).getItems(x, y, w, h)

    def checkCollision(self, location):
        return super(World, self).checkCollision(location)

    # Landscape.
    def getTile(self, x, y):
        loc = (int(x), int(y))
        if loc not in self.tiles:
            return "water"
        return self.tiles[loc]
    
    def setTile(self, x, y, tileName):
        loc = (int(x), int(y))
        self.tiles[loc] = tileName
        self.dirty = True
        return True


    # Loading and Saving via Resources
    def load(self, res, mapName):
        self.tiles = res.loadMap(mapName)
        self.dirty = False
    
    def save(self, res, mapName):
        if self.dirty:
            tiles = self.tiles.items()
            tiles.sort()
            res.saveMap(mapName, tiles)
            self.dirty = False


